package com.adam.test.example.impl;

import com.adam.test.entity.User1;
import com.adam.test.entity.User2;
import com.adam.test.example.PropagationAddExample;
import com.adam.test.service.PropagationAddUser1Service;
import com.adam.test.service.PropagationAddUser2Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author jiangwh
 */
@Service
public class PropagationAddExampleImpl implements PropagationAddExample {
    
    private final PropagationAddUser1Service user1Service;
    
    private final PropagationAddUser2Service user2Service;
    
    @Autowired
    public PropagationAddExampleImpl(PropagationAddUser1Service user1Service, PropagationAddUser2Service user2Service) {
        this.user1Service = user1Service;
        this.user2Service = user2Service;
    }
    
    @Override
    public void truncate() {
        user1Service.truncate();
        user2Service.truncate();
    }

    @Override
    public void noEx_no_no() {
        user1Service.add(createUser1());
        user2Service.add(createUser2());
        throw new IllegalStateException();
    }

    @Override
    public void no_no_noEx() {
        user1Service.add(createUser1());
        user2Service.addThrow(createUser2());
    }

    @Override
    public void noEx_required_required() {
        user1Service.addRequired(createUser1());
        user2Service.addRequired(createUser2());
        throw new IllegalStateException();
    }

    @Override
    public void no_required_requiredEx() {
        user1Service.addRequired(createUser1());
        user2Service.addRequiredThrow(createUser2());
    }

    @Transactional
    @Override
    public void requiredEx_no_no() {
        user1Service.add(createUser1());
        user2Service.add(createUser2());
        throw new IllegalStateException();
    }

    @Transactional
    @Override
    public void required_no_noEx() {
        user1Service.add(createUser1());
        user2Service.addThrow(createUser2());
    }

    @Transactional
    @Override
    public void requiredEx_required_required() {
        user1Service.addRequired(createUser1());
        user2Service.addRequiredThrow(createUser2());
        throw new IllegalStateException();
    }

    @Transactional
    @Override
    public void required_required_requiredEx() {
        user1Service.addRequired(createUser1());
        user2Service.addRequiredThrow(createUser2());
    }

    @Transactional
    @Override
    public void required_required_requiredCatch() {
        user1Service.addRequired(createUser1());
        try {
            user2Service.addRequiredThrow(createUser2());
        } catch (Exception ignored) {}
    }
    
    @Override
    public void noEx_new_new() {
        user1Service.addRequiresNew(createUser1());
        user2Service.addRequiresNew(createUser2());
        throw new IllegalStateException();
    }

    @Override
    public void no_new_newEx() {
        user1Service.addRequiresNew(createUser1());
        user2Service.addRequiresNewThrow(createUser2());
    }

    @Transactional
    @Override
    public void requiredEx_new_new() {
        user1Service.addRequiresNew(createUser1());
        user2Service.addRequiresNew(createUser2());
        throw new IllegalStateException();
    }

    @Transactional
    @Override
    public void required_new_newEx() {
        user1Service.addRequiresNew(createUser1());
        user2Service.addRequiresNewThrow(createUser2());
    }

    @Transactional
    @Override
    public void required_new_newCatch() {
        user1Service.addRequiresNew(createUser1());
        try {
            user2Service.addRequiresNewThrow(createUser2());
        } catch (Exception ignored) {}
    }

    @Override
    public void noEx_nested_nested() {
        user1Service.addNested(createUser1());
        user2Service.addNested(createUser2());
        throw new IllegalStateException();
    }

    @Override
    public void no_nested_nestedEx() {
        user1Service.addNested(createUser1());
        user2Service.addNestedThrow(createUser2());
    }

    @Transactional
    @Override
    public void requiredEx_nested_nested() {
        user1Service.addNested(createUser1());
        user2Service.addNested(createUser2());
        throw new IllegalStateException();
    }

    @Transactional
    @Override
    public void required_nested_nestedEx() {
        user1Service.addNested(createUser1());
        user2Service.addNestedThrow(createUser2());
    }

    @Transactional
    @Override
    public void required_nested_nestedCatch() {
        user1Service.addNested(createUser1());
        try {
            user2Service.addNestedThrow(createUser2());
        } catch (Exception ignored) {}
    }

    @Override
    public void noEx_supports_supports() {
        user1Service.addSupports(createUser1());
        user2Service.addSupports(createUser2());
        throw new IllegalStateException();
    }

    @Override
    public void no_supports_supportsEx() {
        user1Service.addSupports(createUser1());
        user2Service.addSupportsThrow(createUser2());
    }

    @Transactional
    @Override
    public void requiredEx_supports_supports() {
        user1Service.addSupports(createUser1());
        user2Service.addSupports(createUser2());
        throw new IllegalStateException();
    }

    @Transactional
    @Override
    public void required_supports_supportsEx() {
        user1Service.addSupports(createUser1());
        user2Service.addSupportsThrow(createUser2());
    }

    @Transactional
    @Override
    public void required_supports_supportsCatch() {
        user1Service.addSupports(createUser1());
        try {
            user2Service.addSupportsThrow(createUser2());
        } catch (Exception ignored) {}
    }

    @Override
    public void no_mandatory_mandatory() {
        user1Service.addMandatory(createUser1());
        user2Service.addMandatory(createUser2());
    }

    @Transactional
    @Override
    public void requiredEx_mandatory_mandatory() {
        user1Service.addMandatory(createUser1());
        user2Service.addMandatory(createUser2());
        throw new IllegalStateException();
    }

    @Transactional
    @Override
    public void required_mandatory_mandatoryEx() {
        user1Service.addMandatory(createUser1());
        user2Service.addMandatoryThrow(createUser2());
    }

    @Transactional
    @Override
    public void required_mandatory_mandatoryCatch() {
        user1Service.addMandatory(createUser1());
        try {
            user2Service.addMandatoryThrow(createUser2());
        } catch (Exception ignored) {}
    }

    @Transactional
    @Override
    public void requiredEx_not_not() {
        user1Service.addNotSupported(createUser1());
        user2Service.addNotSupported(createUser2());
        throw new IllegalStateException();
    }

    @Transactional
    @Override
    public void required_not_notEx() {
        user1Service.addNotSupported(createUser1());
        user2Service.addNotSupportedThrow(createUser2());
    }

    @Transactional
    @Override
    public void required_not_notCatch() {
        user1Service.addNotSupported(createUser1());
        try {
            user2Service.addNotSupportedThrow(createUser2());
        } catch (Exception ignored) {}
    }

    @Transactional
    @Override
    public void requiredEx_not_required() {
        user1Service.addNotSupported(createUser1());
        user2Service.addRequired(createUser2());
        throw new IllegalStateException();
    }
    
    @Transactional
    @Override
    public void required_required_notEx() {
        user1Service.addRequired(createUser1());
        user2Service.addNotSupportedThrow(createUser2());
    }
    
    @Override
    public void noEx_never_never() {
        user1Service.addNever(createUser1());
        user2Service.addNever(createUser2());
        throw new IllegalStateException();
    }
    
    @Override
    public void no_never_neverEx() {
        user1Service.addNever(createUser1());
        user2Service.addNeverThrow(createUser2());
    }

    @Transactional
    @Override
    public void required_never_never() {
        user1Service.addNever(createUser1());
        user2Service.addNever(createUser2());
    }
    
    private User1 createUser1() {
        User1 user = new User1();
        user.setName("张三");
        return user;
    }
    
    private User2 createUser2() {
        User2 user = new User2();
        user.setName("李四");
        return user;
    }
    
}
